﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Zore.App.Shared.Helpers.Invoker
{
    public class InvokerHelper
    {
        private int TryTimes = 3;
        private int DelayMilliseconds = 1000;
        public string ApiUrl { get; private set; }
        public string ContentType { get; private set; }
        protected InvokerContributor Invoker { get; set; }

        public InvokerHelper(string apiUrl, string contentType = InvokerContants.JsonContentType)
        {
            ApiUrl = apiUrl;
            ContentType = contentType;
            Invoker = CreateInvoker();
        }

        protected async Task<T> Call<T>(Func<Task<T>> action)
        {
            var result = default(T);

            var i = 1;

            while (i <= TryTimes)
            {
                try
                {
                    result = await action();
                    break;
                }
                catch (Exception)
                {
                    if (i >= TryTimes)
                    {
                        throw;
                    }
                    await Task.Delay(DelayMilliseconds);
                }
                i++;
            }
            return result;
        }

        protected async Task Call(Func<Task> action)
        {
            var i = 1;

            while (i <= TryTimes)
            {
                try
                {
                    await action();
                    break;
                }
                catch (Exception)
                {
                    if (i >= TryTimes)
                    {
                        throw;
                    }
                    await Task.Delay(DelayMilliseconds);
                }
                i++;
            }
        }

        protected InvokerContributor CreateInvoker()
        {
            if (ContentType == InvokerContants.FormDataContentType)
            {
                return new FormDataInvoker(ApiUrl);
            }
            if (ContentType == InvokerContants.FormUrlencodedContentType)
            {
                return new FormUrlencodedInvoker(ApiUrl);
            }
            return new NormalInvoker(ApiUrl);
        }
    }
}
